package com.amado.course34Thread.job;

/**
 使用两个线程做龟兔赛跑（乌龟先跑），跑40米: 
 乌龟：速度4m/s 
 兔子：速度5m/s,先在起点睡觉，等乌龟跑到20m后兔子从起点跑 谁先跑完
 */
public class TortoiseRabbitThread2 {
	public static void main(String[] args) {
		Object lock = new Object();
		Tortoise tortoise = new Tortoise(4, 40, lock);
		new Thread(tortoise, "乌龟").start();
		Rabbit rabbit = new Rabbit("兔子", 5, 40, lock);
		rabbit.start();
		
		Rabbit rabbit2 = new Rabbit("兔子2", 5, 40, lock);
		rabbit2.start();
	}

	static class Rabbit extends Thread {
		// 动物速度
		protected int speed;
		// 当前已经跑的路程
		protected int now;
		// 总路径
		protected int mileage;
		private Object lock;

		/**
		 *
		 * @param speed
		 *            速度
		 * @param mileage
		 *            里程
		 */
		Rabbit(String threadName, int speed, int mileage, Object lock) {
			super(threadName);
			this.speed = speed;
			this.mileage = mileage;
			this.lock = lock;
		}

		@Override
		public void run() {
			String threadName = Thread.currentThread().getName();
			try {
				synchronized (lock) {
					System.out.println(threadName + "开始睡觉");
					//在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前，导致当前线程等待
					lock.wait();
					System.out.println(threadName + "结束睡觉，开始跑");
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			while (now < mileage) {
				System.out.println(Thread.currentThread().getName() + "跑了" + now);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				now += speed;
				//now = now +speed
			}
			System.out.println(Thread.currentThread().getName() + "跑完了。。。。");
		}
	}

	static class Tortoise extends Thread {
		// 动物速度
		int speed;
		// 当前已经跑的路程
		int now;
		// 总路径
		int mileage;
		private Object lock;

		/**
		 *
		 * @param speed
		 *            速度
		 * @param mileage
		 *            里程
		 */
		Tortoise(int speed, int mileage, Object lock) {
			this.speed = speed;
			this.mileage = mileage;
			this.lock = lock;
		}

		@Override
		public void run() {
			while (now < mileage) {
				System.out.println(Thread.currentThread().getName() + "跑了" + now);

				// 跑到第20米时，通知兔子开始跑
				if (now == 20) {
					synchronized (lock) {
						System.out.println("通知兔子起来跑");
						//唤醒在此对象监视器上等待的所有线程
						lock.notifyAll();
						//唤醒在此对象监视器上等待的单个线程（选择是任意性的，也就是随机）
//						lock.notify();
					}
				}
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				now += speed;
			}
			System.out.println(Thread.currentThread().getName() + "跑完了。。。。");
		}
	}
}
